package grpc_proxy_middleware

import (
	"fmt"
	"strings"

	"gin-gateway/core/utils"
	"gin-gateway/core/dao"
	"github.com/pkg/errors"
	"google.golang.org/grpc"
	"google.golang.org/grpc/peer"
)

// GrpcWhiteAndBlackListMiddleware
func GrpcWhiteAndBlackListMiddleware(serviceDetail *dao.ServiceDetail) func(srv interface{}, ss grpc.ServerStream, info *grpc.StreamServerInfo, handler grpc.StreamHandler) error {
	return func(srv interface{}, ss grpc.ServerStream, info *grpc.StreamServerInfo, handler grpc.StreamHandler) error {
		peerCtx, ok := peer.FromContext(ss.Context())
		if !ok {
			return errors.New("peer not found with context")
		}
		clientIP := strings.Split(peerCtx.Addr.String(), ":")[0]

		var ipBlackList []string
		if serviceDetail.AccessControl.BlackList != "" {
			ipBlackList = strings.Split(serviceDetail.AccessControl.BlackList, ",")
		}
		if serviceDetail.AccessControl.OpenAuth == 1 && len(ipBlackList) > 0 && utils.StrInSlice(ipBlackList, clientIP) {
			return errors.New(fmt.Sprintf("%s in ip black list", clientIP))
		}

		var ipWhiteList []string
		if serviceDetail.AccessControl.WhiteList != "" && len(ipWhiteList) > 0 && !utils.StrInWhileList(ipWhiteList, clientIP) {
			return errors.New(fmt.Sprintf("%s not in ip white list", clientIP))
		}

		if err := handler(srv, ss); err != nil {
			// log.Printf("RPC failed with error %v\n", err)
			return err
		}
		return nil
	}
}
